package com.sunmouse.paylib;

import android.content.Intent;
import android.os.Bundle;
import android.os.Message;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;

import com.kvin.alipaylib.AuthResult;
import com.kvin.alipaylib.PayResult;
import com.kvin.alipaylib.util.AliUtils;
import com.kvin.paylib.OnChoiceChangedListener;
import com.kvin.paylib.PayPop;
import com.kvin.toolkit.utils.LogUtils;
import com.kvin.toolkit.utils.ThreadPoolUtils;
import com.kvin.toolkit.utils.TipsUtils;
import com.kvin.toolkit.utils.ToastUtils;
import com.kvin.toolkit.utils.http.JsonHttpResponseHandler;
import com.kvin.toolkit.utils.http.JsonUtils;
import com.kvin.toolkit.utils.http.StringHttpResponseHandler;
import com.kvin.unionlib.UnionUtils;
import com.kvin.wechatpay.Cons;
import com.kvin.wechatpay.WXUtils;
import com.sunmouse.paylib.constants.Key;
import com.sunmouse.paylib.utils.HttpUtils;
import com.tencent.mm.opensdk.modelpay.PayReq;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.TimerTask;

import butterknife.BindView;
import butterknife.ButterKnife;

public class MainActivity extends BaseActivity {
    @BindView(R.id.pay_btn)
    Button payBtn;
    @BindView(R.id.pay_method_tv)
    TextView payMethodTv;

    private String orderUrl = "http://101.231.204.84:8091/sim/getacptn";

    private IWXAPI wxAPI;
    private HashMap<String, String> params;


    private TipsUtils mTips;

    private UnionUtils mUnionUtils;
    private AliUtils mAliUtils;
    private WXUtils mWxUtils;
    private PayPop mPop;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
    }

    @Override
    public void init() {
        mTips = TipsUtils.getInstance(this);
        mPop = PayPop.getInstance(this);
        mPop.setOnChoiceChangedListener(mOnChoiceChangedListener);
        mJsonUtils = JsonUtils.getInstance();
        this.payMethodTv.setOnClickListener(this);
        payBtn.setOnClickListener(this);

        mUnionUtils = UnionUtils.getInstance(this);
        mAliUtils = AliUtils.getInstance(this);
//        mWxUtils = WXUtils.getInstance(this, "wx5619ce757b7d47f7");
        mWxUtils = WXUtils.getInstance(this, "wxb4ba3c02aa476ea1");//test
    }


    /**
     * show tips
     *
     * @param
     */
    public void showTips(String title, String msg, View.OnClickListener cancelListener, View.OnClickListener submitListener) {
        mTips.setTitle(title);
        mTips.setDesc(msg);
        mTips.setOnCancelClickListener(cancelListener);
        mTips.setOnConfirmClickListener(submitListener);
        mTips.show();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.pay_method_tv:
                mPop.show(payBtn, Gravity.BOTTOM);
                break;
            case R.id.pay_btn:
                launchPay();
                break;
        }
    }

    private void launchPay() {
        int index = mPop.getCurrentIndex();
        if (index == PayPop.PAY_ALI) {
            alipay();
        } else if (index == PayPop.PAY_WECHAT) {
            wechatPay();
        } else if (index == PayPop.PAY_UNION) {
            unionPay();
        }
    }

    /**
     * on choice changed listener
     */
    private OnChoiceChangedListener mOnChoiceChangedListener = new OnChoiceChangedListener() {
        @Override
        public void onChoiceChanged(RadioGroup group, int index) {
            payMethodTv.setText(mPop.getCurrentText());
            mPop.dismiss();
        }
    };

    /**
     * union pay
     */
    private void unionPay() {
        params = HttpUtils.unionJsonParams();
//        mJsonUtils.post(HttpUtils.UNION_URL, params, new JsonHttpResponseHandler() {
//            @Override
//            public void onSuccess(JSONObject response) {
//                super.onSuccess(response);
//                if (response == null) return;
//                try {
//                    String tn = response.getString("orderNo");
//                    doStartUnionPayPlugin(getActivity(), tn, mMode);
//                } catch (JSONException e) {
//                    e.printStackTrace();
//                }
//            }
//
//            @Override
//            public void onFailure(IOException e) {
//                super.onFailure(e);
//            }
//        });
        mJsonUtils.get(orderUrl, null, new StringHttpResponseHandler() {
            @Override
            public void onSuccess(String response) {
                super.onSuccess(response);
                int ret = mUnionUtils.unionPay(response, UnionUtils.ENVI_DEBUG);
                if (ret == UnionUtils.PLUGIN_NEED_UPGRADE || ret == UnionUtils.PLUGIN_NOT_INSTALLED) {
                    mUnionUtils.showPluginDialog("提示", "需要安装银联插件以完成支付", null, null);
                    return;
                }
            }
        });

    }

    /**
     * wechat
     */
    private void wechatPay() {
        if (!mWxUtils.isPaySupported()) {
            ToastUtils.simpleToast(this, "抱歉，您的机器不支持微信支付");
            return;
        }
        params = HttpUtils.wechatJsonParams();
        mJsonUtils.post(HttpUtils.WECHAT_URL, null, new JsonHttpResponseHandler() {
            @Override
            public void onSuccess(JSONObject response) {
                super.onSuccess(response);
                if (response == null) return;
                boolean status=mWxUtils.wechatPay(response);
                LogUtils.v("---status="+status);
            }

            @Override
            public void onFailure(IOException e) {
                super.onFailure(e);
            }
        });

        //test
//        ThreadPoolUtils.execute(new Runnable() {
//            @Override
//            public void run() {
//                PayReq req = new PayReq();
//                req.appId="wx5619ce757b7d47f7";
//                req.partnerId = "1505021711";
//                req.prepayId = "wx081453458064896a97384b4e0282717134";
//                req.nonceStr = "5Uj6NQYhRwnaRRxk";
//                req.timeStamp = "1528440820";
//                req.packageValue = "Sign=WXPay";
//                req.sign = ":38B68899D1B11383A07B7B2768FA333D";
//                req.extData = "app data"; // optional
//                boolean status=mWxUtils.wechatPay(req);
//                LogUtils.v("---status="+status);
//            }
//        });

//        ToastUtils.simpleToast(this,status?"支付成功":"支付失败");
    }

    private void launchWechatPay(final PayReq req) {


        ThreadPoolUtils.execute(new TimerTask() {
            @Override
            public void run() {
                wxAPI.sendReq(req);
            }
        });

    }


    /**
     * alipay related
     */
    private void alipay() {
        HashMap<String, String> params = HttpUtils.alipayJsonParams();

        mJsonUtils.post(HttpUtils.ALIPAY_URL, params, new JsonHttpResponseHandler() {
            @Override
            public void onSuccess(JSONObject response) {
                super.onSuccess(response);
                if (response == null) return;
                try {
                    String orderInfo = response.getString("oderString");
                    launchAlipay(orderInfo);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                //String s=response.toString();
            }

            @Override
            public void onFailure(IOException e) {
                super.onFailure(e);
            }
        });
    }

    private void launchAlipay(final String orderInfo) {
        ThreadPoolUtils.execute(new TimerTask() {
            @Override
            public void run() {
                if (TextUtils.isEmpty(orderInfo)) {
                    ToastUtils.simpleToast(getActivity(), "获取订单信息失败");
                    return;
                }
                mMsg = Message.obtain();
                mMsg.what = Key.Flag.PAY;
                mMsg.obj = mAliUtils.aliPay(orderInfo);
                mHanlder.sendMessage(mMsg);
            }
        });
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (data == null) return;
        String msg = "";
        /*
         * union response
         */
        String str = data.getExtras().getString(UnionUtils.Tag.PAY_RESULT);
        if (str.equalsIgnoreCase(UnionUtils.Tag.SUCCESS)) {
            // 如果想对结果数据验签，可使用下面这段代码，但建议不验签，直接去商户后台查询交易结果
            // result_data结构见c）result_data参数说明
            if (data.hasExtra(UnionUtils.Tag.RESULT_DATA)) {
                String result = data.getExtras().getString(UnionUtils.Tag.RESULT_DATA);
                try {
                    JSONObject resultJson = new JSONObject(result);
                    String sign = resultJson.getString(UnionUtils.Tag.SIGN);
                    String dataOrg = resultJson.getString(UnionUtils.Tag.DATA);
                    // 此处的verify建议送去商户后台做验签
                    // 如要放在手机端验，则代码必须支持更新证书
                    boolean ret = mUnionUtils.verifySign(dataOrg, sign, UnionUtils.ENVI_PUBLISH);
                    if (ret) {
                        // 验签成功，显示支付结果
                        msg = "支付成功！";
                    } else {
                        // 验签失败
                        msg = "支付失败！";
                    }
                } catch (JSONException e) {
                }
            }
            // 结果result_data为成功时，去商户后台查询一下再展示成功
            msg = "支付成功！";
        } else if (str.equalsIgnoreCase("fail")) {
            msg = "支付失败！";
        } else if (str.equalsIgnoreCase("cancel")) {
            msg = "用户取消了支付";
        }
        showTips("银联支付结果通知", msg, null, null);
    }


    @Override
    public void onHandleMessage(Message msg) {
        switch (msg.what) {
            case Key.Flag.PAY: {
                @SuppressWarnings("unchecked")
                PayResult payResult = AliUtils.getPayResult((Map<String, String>) msg.obj);
                /**
                 对于支付结果，请商户依赖服务端的异步通知结果。同步通知结果，仅作为支付结束的通知。
                 */
                String resultInfo = payResult.getResult();// 同步返回需要验证的信息
                String resultStatus = payResult.getResultStatus();
                // 判断resultStatus 为9000则代表支付成功
                if (TextUtils.equals(resultStatus, "9000")) {
                    // 该笔订单是否真实支付成功，需要依赖服务端的异步通知。
                    Toast.makeText(getActivity(), "支付成功", Toast.LENGTH_SHORT).show();
                } else {
                    // 该笔订单真实的支付结果，需要依赖服务端的异步通知。
                    Toast.makeText(getActivity(), "支付失败", Toast.LENGTH_SHORT).show();
                }
                break;
            }
            case Key.Flag.AUTH: {
                @SuppressWarnings("unchecked")
                AuthResult authResult = AliUtils.getAuthResult((Map<String, String>) msg.obj, true);
                String resultStatus = authResult.getResultStatus();
                // 判断resultStatus 为“9000”且result_code
                // 为“200”则代表授权成功，具体状态码代表含义可参考授权接口文档
                if (TextUtils.equals(resultStatus, "9000") && TextUtils.equals(authResult.getResultCode(), "200")) {
                    // 获取alipay_open_id，调支付时作为参数extern_token 的value
                    // 传入，则支付账户为该授权账户
                    Toast.makeText(getActivity(),
                            "授权成功\n" + String.format("authCode:%s", authResult.getAuthCode()), Toast.LENGTH_SHORT)
                            .show();
                } else {
                    // 其他状态值则为授权失败
                    Toast.makeText(getActivity(),
                            "授权失败" + String.format("authCode:%s", authResult.getAuthCode()), Toast.LENGTH_SHORT).show();

                }
                break;
            }
            case Key.Flag.ORDER_INFO:
                break;
            case Key.Flag.PLUGIN_NOT_INSTALLED:
                break;
            case Key.Flag.PLUGIN_NEED_UPGRADE:
                break;
            default:
                break;
        }
    }
}
